package com.android.server.mock.storage;


import android.os.mock.storage.MockStructStatVfs;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * Mock StatFs impl {@link android.os.StatFs#StatFs(String)}
 */
public class MockStatFsImpl {
    private static final String TAG = MockStatFsImpl.class.getSimpleName();

    private static MockStatFsImpl mockStatFs;

    private Map<String, MockStructStatVfs> mockStructStatVfsMap = new HashMap<>();

    public static MockStatFsImpl getInstance() {
        synchronized (MockStatFsImpl.class) {
            if (mockStatFs == null) {
                mockStatFs = new MockStatFsImpl();
            }
            return mockStatFs;
        }
    }

    public boolean parseStatfsInfo(JSONObject deviceInfo) {
        boolean result = false;

        try {
            if (deviceInfo.has("statfs")) {
                JSONObject statfs = deviceInfo.getJSONObject("statfs");
                Log.d(TAG, "parseStatfsInfo statfs json: " + statfs.toString());
                if(statfs != null) {

                    //parse data statfs
                    if(statfs.has("dataStatf")) {
                        JSONObject dataStatf = statfs.getJSONObject("dataStatf");
                        Log.d(TAG, "parseStatfsInfo dataStatf json: " + dataStatf.toString());
                        if(null != dataStatf) {
                            MockStructStatVfs mockDataStatFs = buildMockStructStatVfs(dataStatf);
                            if(null != mockDataStatFs) {
                                mockStructStatVfsMap.put(mockDataStatFs.path, mockDataStatFs);
                            }
                        }
                    }

                    //parse system statfs
                    if(statfs.has("systemStatf")) {
                        JSONObject systemStatf = statfs.getJSONObject("systemStatf");
                        if(null != systemStatf) {
                            MockStructStatVfs mockSystemStatFs = buildMockStructStatVfs(systemStatf);
                            if(null != mockSystemStatFs) {
                                mockStructStatVfsMap.put(mockSystemStatFs.path, mockSystemStatFs);
                            }
                        }
                    }

                    //parse vendor statfs
                    if(statfs.has("vendorStatf")) {
                        JSONObject vendorStatf = statfs.getJSONObject("vendorStatf");
                        if(null != vendorStatf) {
                            MockStructStatVfs mockVendorStatFs = buildMockStructStatVfs(vendorStatf);
                            if(null != mockVendorStatFs) {
                                mockStructStatVfsMap.put(mockVendorStatFs.path, mockVendorStatFs);
                            }
                        }
                    }

                    result = true;
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "parseStatfsInfo: ", e);
        }

        return result;
    }

    public MockStructStatVfs buildMockStructStatVfs(JSONObject statFs) {
        MockStructStatVfs mockStructStatVfs = new MockStructStatVfs();
        try {
            mockStructStatVfs.path = statFs.getString("path");
            mockStructStatVfs.f_bavail = statFs.getLong("f_bavail");
            mockStructStatVfs.f_bfree = statFs.getLong("f_bfree");
            mockStructStatVfs.f_blocks = statFs.getLong("f_blocks");
            mockStructStatVfs.f_bsize = statFs.getLong("f_bsize");
            mockStructStatVfs.f_favail = statFs.getLong("f_favail");
            mockStructStatVfs.f_ffree = statFs.getLong("f_ffree");
            mockStructStatVfs.f_files = statFs.getLong("f_files");
            mockStructStatVfs.f_flag = statFs.getLong("f_flag");
            mockStructStatVfs.f_frsize = statFs.getLong("f_frsize");
            mockStructStatVfs.f_fsid = statFs.getLong("f_fsid");
            mockStructStatVfs.f_namemax = statFs.getLong("f_namemax");

            Log.d(TAG, "buildMockStructStatVfs: " + mockStructStatVfs);
        } catch (JSONException e) {
            mockStructStatVfs = null;
            Log.e(TAG, "buildMockStructStatVfs: ", e);
        }

        return mockStructStatVfs;
    }

    public Map<String, MockStructStatVfs> getMockStructStatVfsMap() {
        return mockStructStatVfsMap;
    }

    public void resetMockStructStatVfs() {
        mockStructStatVfsMap.clear();
    }
 }
